/*
    This file is part of FNote.

    FNote is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    FNote is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with FNote.  If not, see <http://www.gnu.org/licenses/>.

    Copyright (c) 2009, Maciej "Fazi" Gałkowski <fazi.dev@gmail.com>
*/
#include <QtGui>

#include "fnote-config.h"
#include "mainwindow.h"

void showError(const QString &title, const QString &message);
void printVersion();
void printUsage();
void printGeneralOptions();
void printOptions();
void printQtOptions();

static QTextStream out(stdout);
static QTextStream err(stderr);

/* **** */
int main(int argc, char *argv[])
{
    Q_INIT_RESOURCE(fnote);

    QApplication *app = new QApplication(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

    // check tray availability
    if(!QSystemTrayIcon::isSystemTrayAvailable())
    {
        showError(QObject::tr("Systray"), QObject::tr("I couldn't detect any system tray on this system."));
        delete app;
        return 1;
    }

    QApplication::setApplicationName("FNote");
    QApplication::setApplicationVersion(FULLVERSION);
    // QApplication::setOrganizationName("");
    // QApplication::setOrganizationDomain("")

    QApplication::setQuitOnLastWindowClosed(false);

    // parse command line (parsed already by QT itself)
    QString configDir(DEFAULT_CONFIGDIR);
    QStringList args(app->arguments());
    int size = args.size();
    QString param;
    QString test;

    for(int i = 1; i < size; ++i)
    {
        param = args.at(i);
        if(param == "--help" || param == "-h")
        {
            printUsage(); out << "\n";
            printGeneralOptions(); out << "\n";
            printOptions();

            delete app;
            return 0;
        }
        else if(param == "--help-all")
        {
            printUsage(); out << "\n";
            printGeneralOptions(); out << "\n";
            printQtOptions(); out << "\n";
            printOptions();

            delete app;
            return 0;
        }
        else if(param == "--help-qt")
        {
            printUsage(); out << "\n";
            printQtOptions();

            delete app;
            return 0;
        }
        else if(param == "--version" || param == "-v")
        {
            printVersion();

            delete app;
            return 0;
        }
        else if(param == "--config-dir" || param == "-c")
        {
            ++i;
            if(i < size)
            {
                configDir = args.at(i);
            }
            else
            {
                err << QObject::tr("Option \"%1\" requires an argument, ignoring").arg(param) << endl;
            }
        }
        else
        {
            err << QObject::tr("Unknown option \"%1\", ignoring").arg(param) << endl;
        }
    }


    QDir dir(configDir);
    configDir = dir.absolutePath();
    QFileInfo fileInfo(configDir);

    if(dir.exists() && fileInfo.isReadable())
    {
        out << QObject::tr("Using config dir \"%1\"").arg(configDir) << endl;
    }
    else
    {
        out << QObject::tr("Provided config dir \"%1\" doesn't exist or is not accessible.").arg(configDir) << "\n" << QObject::tr("Falling back to \"%1\"").arg(DEFAULT_CONFIGDIR) << endl;
        configDir = DEFAULT_CONFIGDIR;
    }

    // start the app
    int ret = 0;
    try
    {
        MainWindow window(configDir);
        int ret = app->exec();
    }
    catch(QString &e)
    {
        showError(QObject::tr("FNote"), e);
        ret = 2;
    }

    delete app;
    return ret;
}

inline void showError(const QString &title, const QString &message)
{
    QMessageBox::critical(0, title, message);
    fprintf(stderr, "FNote fatal error: %s\n", qPrintable(message));
    fflush(stderr);
}

inline void printVersion()
{
    out << QObject::tr("FNote, version %1\nCompiled on %2, %3\nCopyright (c) 2009, Maciej \"Fazi\" Gałkowski <fazi.dev@gmail.com>\n\nQt version: %4 (compiled), %5 (running)").arg(FULLVERSION).arg(__DATE__).arg(__TIME__).arg(QT_VERSION_STR).arg(qVersion()) << "\n";

    out.flush();
}

inline void printUsage()
{
    out << QObject::tr("Usage: fnote [Qt options] [General options] [Options]") << "\n";

    out.flush();
}

inline void printQtOptions()
{
    out << QObject::tr("Qt Options:") << "\n";

#ifdef Q_WS_X11
    out << "\t-display <displayname>\t" << QObject::tr("Use the X-server display 'displayname'") << "\n";
#elif defined(Q_WS_QWS)
    out << "\t-display <displayname>\t" << QObject::tr("Use the QWS display 'displayname'") << "\n";
#else
#endif
    out << "\t-session <sessionId>\t" << QObject::tr("Restore the application for the given 'sessionId'") << "\n";
    out << "\t-cmap\t\t\t" << QObject::tr("Causes the application to install a private color map on an 8-bit display") << "\n";
    out << "\t-ncols <count>\t\t" << QObject::tr("Limits the number of colors allocated in the color cube on an 8-bit display, if the application is using the QApplication::ManyColor color specification") << "\n";
    out << "\t-nograb\t\t\t" << QObject::tr("Tells Qt to never grab the mouse or the keyboard") << "\n";
    out << "\t-dograb\t\t\t" << QObject::tr("Running under a debugger can cause an implicit -nograb, use -dograb to override") << "\n";
    out << "\t-sync\t\t\t" << QObject::tr("Switches to synchronous mode for debugging") << "\n";
    out << "\t-fn, -font <fontname>\t" << QObject::tr("defines the application font") << "\n";
    out << "\t-bg, -background <color> " << QObject::tr("Sets the default background color and an application palette (light and dark shades are calculated)") << "\n";
    out << "\t-fg, -foreground <color> " << QObject::tr("Sets the default foreground color") << "\n";
    out << "\t-btn, -button <color>\t" << QObject::tr("Sets the default button color") << "\n";
    out << "\t-name <name>\t\t" << QObject::tr("Sets the application name") << "\n";
    out << "\t-title <title>\t\t" << QObject::tr("Sets the application title (caption)") << "\n";
#ifdef Q_WS_X11
    out << "\t-visual TrueColor\t" << QObject::tr("Forces the application to use a TrueColor visual on an 8-bit display") << "\n";
    out << "\t-inputstyle <inputstyle> " << QObject::tr("Sets XIM (X Input Method) input style. Possible values are onthespot, overthespot, offthespot and root") << "\n";
    out << "\t-im <XIM server>\t" << QObject::tr("Set XIM server") << "\n";
    out << "\t-noxim\t\t\t" << QObject::tr("Disable XIM") << "\n";
#endif
#ifdef Q_WS_QWS
    out << "\t-qws\t\t\t" << QObject::tr("Forces the application to run as QWS Server") << "\n";
#endif
    out << "\t-reverse\t\t" << QObject::tr("Mirrors the whole layout of widgets") << "\n";

    out.flush();
}

inline void printGeneralOptions()
{
    out << QObject::tr("General Options:") << "\n";
    out << "\t-h, --help\t\t" << QObject::tr("Print FNote options.") << "\n";
    out << "\t--help-qt\t\t" << QObject::tr("Print Qt options") << "\n";
    out << "\t--help-all\t\t" << QObject::tr("Print all options") << "\n";
    out << "\t-v, --version\t\t" << QObject::tr("Print version") << "\n";

    out.flush();
}

inline void printOptions()
{
    out << QObject::tr("Options:") << "\n";
    out << "\t-c, --config-dir <dir>\t" << QObject::tr("Set configuration directory") << "\n";

    out.flush();
}